<template>
  <div class="apple-input-wrapper" :class="wrapperClasses">
    <!-- 标签 -->
    <label v-if="label" :for="inputId" class="input-label">
      {{ label }}
      <span v-if="required" class="input-required">*</span>
    </label>

    <!-- 输入框容器 -->
    <div class="input-container">
      <!-- 前置图标 -->
      <div v-if="prefixIcon" class="input-prefix">
        <component :is="prefixIcon" class="input-icon" />
      </div>

      <!-- 输入框 -->
      <component
        :is="inputComponent"
        :id="inputId"
        ref="inputRef"
        :class="inputClasses"
        :type="computedType"
        :value="modelValue"
        :placeholder="placeholder"
        :disabled="disabled"
        :readonly="readonly"
        :maxlength="maxlength"
        :minlength="minlength"
        :max="max"
        :min="min"
        :step="step"
        :rows="rows"
        :cols="cols"
        :autocomplete="autocomplete"
        :autofocus="autofocus"
        :pattern="pattern"
        :list="list"
        @input="handleInput"
        @change="handleChange"
        @focus="handleFocus"
        @blur="handleBlur"
        @keydown="handleKeydown"
        @keyup="handleKeyup"
        @keypress="handleKeypress"
      />

      <!-- 后置内容 -->
      <div v-if="hasPostfixContent" class="input-postfix">
        <!-- 清除按钮 -->
        <button
          v-if="clearable && modelValue && !disabled && !readonly"
          type="button"
          class="input-clear"
          @click="handleClear"
        >
          ✕
        </button>

        <!-- 密码显示切换 -->
        <button
          v-if="type === 'password' && passwordToggle"
          type="button"
          class="input-password-toggle"
          @click="togglePassword"
        >
          {{ showPassword ? '🙈' : '👁️' }}
        </button>

        <!-- 后置图标 -->
        <component
          v-if="suffixIcon"
          :is="suffixIcon"
          class="input-icon"
        />

        <!-- 字符计数 -->
        <span v-if="showCount && maxlength" class="input-count">
          {{ modelValue?.length || 0 }}/{{ maxlength }}
        </span>
      </div>
    </div>

    <!-- 帮助文本 -->
    <div v-if="helpText" class="input-help">
      {{ helpText }}
    </div>

    <!-- 错误信息 -->
    <div v-if="errorMessage" class="input-error">
      {{ errorMessage }}
    </div>

    <!-- 成功信息 -->
    <div v-if="successMessage" class="input-success">
      {{ successMessage }}
    </div>
  </div>
</template>

<script setup lang="ts">
import { computed, ref, nextTick } from 'vue'

// Props定义
interface Props {
  // v-model值
  modelValue?: string | number
  // 输入框类型
  type?: 'text' | 'password' | 'email' | 'number' | 'tel' | 'url' | 'search' | 'textarea'
  // 标签
  label?: string
  // 占位符
  placeholder?: string
  // 是否必填
  required?: boolean
  // 是否禁用
  disabled?: boolean
  // 是否只读
  readonly?: boolean
  // 是否可清除
  clearable?: boolean
  // 密码切换
  passwordToggle?: boolean
  // 显示字符计数
  showCount?: boolean
  // 尺寸
  size?: 'small' | 'medium' | 'large'
  // 状态
  status?: 'default' | 'error' | 'success' | 'warning'
  // 前置图标
  prefixIcon?: any
  // 后置图标
  suffixIcon?: any
  // 帮助文本
  helpText?: string
  // 错误信息
  errorMessage?: string
  // 成功信息
  successMessage?: string
  // HTML属性
  maxlength?: number
  minlength?: number
  max?: number | string
  min?: number | string
  step?: number | string
  rows?: number
  cols?: number
  autocomplete?: string
  autofocus?: boolean
  pattern?: string
  list?: string
}

// Emits定义
interface Emits {
  (e: 'update:modelValue', value: string | number): void
  (e: 'input', value: string | number, event: Event): void
  (e: 'change', value: string | number, event: Event): void
  (e: 'focus', event: FocusEvent): void
  (e: 'blur', event: FocusEvent): void
  (e: 'clear'): void
  (e: 'keydown', event: KeyboardEvent): void
  (e: 'keyup', event: KeyboardEvent): void
  (e: 'keypress', event: KeyboardEvent): void
}

const props = withDefaults(defineProps<Props>(), {
  type: 'text',
  size: 'medium',
  status: 'default',
  passwordToggle: true,
  clearable: false,
  showCount: false,
  required: false,
  disabled: false,
  readonly: false,
  autofocus: false
})

const emit = defineEmits<Emits>()

// 内部状态
const inputRef = ref<HTMLInputElement | HTMLTextAreaElement>()
const isFocused = ref(false)
const showPassword = ref(false)

// 生成唯一ID
const inputId = `apple-input-${Math.random().toString(36).substr(2, 9)}`

// 计算属性
const inputComponent = computed(() => {
  return props.type === 'textarea' ? 'textarea' : 'input'
})

const computedType = computed(() => {
  if (props.type === 'password') {
    return showPassword.value ? 'text' : 'password'
  }
  return props.type === 'textarea' ? undefined : props.type
})

const wrapperClasses = computed(() => {
  const classes = ['apple-input-wrapper']
  
  if (props.size !== 'medium') {
    classes.push(`apple-input-wrapper--${props.size}`)
  }
  
  if (props.status !== 'default') {
    classes.push(`apple-input-wrapper--${props.status}`)
  }
  
  if (props.disabled) {
    classes.push('apple-input-wrapper--disabled')
  }
  
  if (props.readonly) {
    classes.push('apple-input-wrapper--readonly')
  }
  
  if (isFocused.value) {
    classes.push('apple-input-wrapper--focused')
  }
  
  return classes
})

const inputClasses = computed(() => {
  const classes = ['apple-input']
  
  if (props.prefixIcon) {
    classes.push('apple-input--with-prefix')
  }
  
  if (hasPostfixContent.value) {
    classes.push('apple-input--with-postfix')
  }
  
  return classes
})

const hasPostfixContent = computed(() => {
  return (
    (props.clearable && props.modelValue && !props.disabled && !props.readonly) ||
    (props.type === 'password' && props.passwordToggle) ||
    props.suffixIcon ||
    (props.showCount && props.maxlength)
  )
})

// 事件处理
const handleInput = (event: Event) => {
  const target = event.target as HTMLInputElement | HTMLTextAreaElement
  const value = props.type === 'number' ? Number(target.value) : target.value
  emit('update:modelValue', value)
  emit('input', value, event)
}

const handleChange = (event: Event) => {
  const target = event.target as HTMLInputElement | HTMLTextAreaElement
  const value = props.type === 'number' ? Number(target.value) : target.value
  emit('change', value, event)
}

const handleFocus = (event: FocusEvent) => {
  isFocused.value = true
  emit('focus', event)
}

const handleBlur = (event: FocusEvent) => {
  isFocused.value = false
  emit('blur', event)
}

const handleClear = () => {
  emit('update:modelValue', '')
  emit('clear')
  nextTick(() => {
    inputRef.value?.focus()
  })
}

const togglePassword = () => {
  showPassword.value = !showPassword.value
  nextTick(() => {
    inputRef.value?.focus()
  })
}

const handleKeydown = (event: KeyboardEvent) => {
  emit('keydown', event)
}

const handleKeyup = (event: KeyboardEvent) => {
  emit('keyup', event)
}

const handleKeypress = (event: KeyboardEvent) => {
  emit('keypress', event)
}

// 公开方法
const focus = () => {
  inputRef.value?.focus()
}

const blur = () => {
  inputRef.value?.blur()
}

const select = () => {
  if (inputRef.value && 'select' in inputRef.value) {
    inputRef.value.select()
  }
}

defineExpose({
  focus,
  blur,
  select,
  inputRef
})
</script>

<style scoped>
.apple-input-wrapper {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-xs);
  width: 100%;
}

.input-label {
  display: block;
  font-size: 14px;
  font-weight: 500;
  color: var(--text-primary);
  line-height: 1.4;
  cursor: pointer;
}

.input-required {
  color: var(--color-danger);
  margin-left: 2px;
}

.input-container {
  position: relative;
  display: flex;
  align-items: center;
}

.apple-input {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid var(--border-primary);
  border-radius: var(--radius-medium);
  font-family: inherit;
  font-size: 14px;
  line-height: 1.4;
  color: var(--text-primary);
  background-color: var(--bg-primary);
  transition: all var(--duration-fast) var(--ease-out);
  outline: none;
  appearance: none;

  &::placeholder {
    color: var(--text-tertiary);
  }

  &:focus {
    border-color: var(--color-primary);
    box-shadow: 0 0 0 3px rgba(0, 122, 255, 0.1);
  }

  &:disabled {
    background-color: var(--bg-tertiary);
    color: var(--text-tertiary);
    cursor: not-allowed;
  }

  &:readonly {
    background-color: var(--bg-secondary);
    cursor: default;
  }
}

.apple-input--with-prefix {
  padding-left: 40px;
}

.apple-input--with-postfix {
  padding-right: 40px;
}

.input-prefix,
.input-postfix {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  gap: var(--spacing-xs);
  color: var(--text-tertiary);
  pointer-events: none;
}

.input-prefix {
  left: 12px;
}

.input-postfix {
  right: 12px;
}

.input-clear,
.input-password-toggle {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  padding: 0;
  border: none;
  border-radius: 50%;
  background-color: transparent;
  color: var(--text-tertiary);
  cursor: pointer;
  pointer-events: auto;
  transition: all var(--duration-fast) var(--ease-out);

  &:hover {
    background-color: var(--bg-tertiary);
    color: var(--text-secondary);
  }
}

.input-icon {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
}

.input-count {
  font-size: 11px;
  color: var(--text-tertiary);
  white-space: nowrap;
  pointer-events: auto;
}

.input-help {
  font-size: 12px;
  color: var(--text-tertiary);
  line-height: 1.4;
}

.input-error {
  font-size: 12px;
  color: var(--color-danger);
  line-height: 1.4;
}

.input-success {
  font-size: 12px;
  color: var(--color-success);
  line-height: 1.4;
}

/* 尺寸变体 */
.apple-input-wrapper--small .apple-input {
  padding: 6px 10px;
  font-size: 12px;
  border-radius: var(--radius-small);
}

.apple-input-wrapper--small .apple-input--with-prefix {
  padding-left: 32px;
}

.apple-input-wrapper--small .apple-input--with-postfix {
  padding-right: 32px;
}

.apple-input-wrapper--small .input-prefix {
  left: 10px;
}

.apple-input-wrapper--small .input-postfix {
  right: 10px;
}

.apple-input-wrapper--large .apple-input {
  padding: 14px 16px;
  font-size: 16px;
  border-radius: var(--radius-large);
}

.apple-input-wrapper--large .apple-input--with-prefix {
  padding-left: 48px;
}

.apple-input-wrapper--large .apple-input--with-postfix {
  padding-right: 48px;
}

.apple-input-wrapper--large .input-prefix {
  left: 16px;
}

.apple-input-wrapper--large .input-postfix {
  right: 16px;
}

/* 状态变体 */
.apple-input-wrapper--error .apple-input {
  border-color: var(--color-danger);

  &:focus {
    border-color: var(--color-danger);
    box-shadow: 0 0 0 3px rgba(255, 59, 48, 0.1);
  }
}

.apple-input-wrapper--success .apple-input {
  border-color: var(--color-success);

  &:focus {
    border-color: var(--color-success);
    box-shadow: 0 0 0 3px rgba(52, 199, 89, 0.1);
  }
}

.apple-input-wrapper--warning .apple-input {
  border-color: var(--color-warning);

  &:focus {
    border-color: var(--color-warning);
    box-shadow: 0 0 0 3px rgba(255, 149, 0, 0.1);
  }
}

/* 文本域特殊样式 */
textarea.apple-input {
  resize: vertical;
  min-height: 80px;
  line-height: 1.5;
}

/* 数字输入框特殊样式 */
input[type="number"].apple-input {
  -moz-appearance: textfield;
}

input[type="number"].apple-input::-webkit-outer-spin-button,
input[type="number"].apple-input::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

/* 搜索框特殊样式 */
input[type="search"].apple-input {
  -webkit-appearance: none;
}

input[type="search"].apple-input::-webkit-search-decoration,
input[type="search"].apple-input::-webkit-search-cancel-button,
input[type="search"].apple-input::-webkit-search-results-button,
input[type="search"].apple-input::-webkit-search-results-decoration {
  -webkit-appearance: none;
}

/* 暗色模式适配 */
@media (prefers-color-scheme: dark) {
  .apple-input {
    background-color: var(--bg-secondary);
    border-color: var(--border-secondary);
  }

  .apple-input:disabled {
    background-color: var(--bg-tertiary);
  }
}

/* 高对比度模式 */
@media (prefers-contrast: high) {
  .apple-input {
    border-width: 2px;
  }

  .apple-input:focus {
    border-width: 3px;
  }
}

/* 响应式设计 */
@media (max-width: 768px) {
  .apple-input {
    min-height: 44px; /* Apple推荐的最小触摸目标尺寸 */
  }
  
  .apple-input-wrapper--small .apple-input {
    min-height: 36px;
  }
  
  .apple-input-wrapper--large .apple-input {
    min-height: 52px;
  }
}
</style>